package xyz.scootaloo.kami.server.standard

import io.vertx.core.buffer.Buffer
import io.vertx.core.json.JsonArray
import io.vertx.core.json.JsonObject
import org.jetbrains.annotations.NotNull
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.sql.Timestamp

/**
 * 不影响语义的情况下, 提供一些便捷的方法
 *
 * @author flutterdash@qq.com
 * @since 2021/12/31 15:59
 */

val STATIC_LOG: Logger by lazy { LoggerFactory.getLogger("GLOBAL") }

val Any.classname: String get() = this.javaClass.name

val Any.simpleClassname: String get() = this.javaClass.simpleName

fun Any.getLogger(): Logger = LoggerFactory.getLogger(this.javaClass)

fun <T> Iterable<T>.ignoreNullElements(): List<T> = mapNotNull { e -> e }

fun Any.toJsonBuff(): Buffer = internalAny2JsonBuff(this)

fun Any.toJsonObject(): JsonObject = JsonObject.mapFrom(this)

fun String.split2PathItems(): List<String> = this.replace('\\', '/').split('/').filter { it.isNotBlank() }

fun JsonObject.safeGetInteger(key: String, def: Int): Int = safeCall1(def, key, ::getInteger)

fun JsonObject.safeGetString(key: String, def: String): String = safeCall1(def, key, ::getString)

fun JsonObject.safeGetArray(key: String, def: JsonArray): JsonArray = safeCall1(def, key, ::getJsonArray)

fun timestamp(): String = timestamp(currentTimeMillis())

fun timestamp(time: Long): String = Timestamp(time).toString()

fun currentTimeMillis(): Long = System.currentTimeMillis()

fun Logger.internalErrorHandle(e: Throwable): Boolean {
    if (e is ServerInternalException) {
        when (e.level) {
            ExceptionLevel.INFO -> warn(e.message)
            ExceptionLevel.ERROR -> error(e.message, e)
            else -> {
                return false
            }
        }
        return true;
    } else {
        error(e.message, e)
        return true;
    }
}

private fun <In, Out> safeCall1(def: Out, input: In, method: (In) -> Out): Out = try {
    method(input)
} catch (ignore: Throwable) {
    def
}

private fun internalAny2JsonBuff(@NotNull obj: Any): Buffer {
    return if (obj is JsonObject) {
        obj.toBuffer()
    } else {
        obj.toJsonObject().toBuffer()
    }
}